<?php
// +----------------------------------------------------------------------
// | 有小象汇 自研正版源码 赋能开发者
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 http://www.uxphp.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 有小象汇并不是自由软件，未经许可不能去掉有小象汇相关版权
// +----------------------------------------------------------------------
// | Author:  有小象汇
// +----------------------------------------------------------------------

namespace app\services\care;

use app\listener\task\Send;
use app\model\care\ServiceOrder;
use app\model\jiyun\Order;
use app\services\BaseServices;
use app\services\pay\PayServices;
use app\services\user\UserMoneyServices;
use app\services\user\UserServices;
use app\services\wechat\WechatUserServices;
use think\exception\ValidateException;
use app\services\message\notice\RoutineTemplateListService;
use app\services\activity\lottery\LuckLotteryServices;
use app\services\wechat\WechatServices;

/**
 * 订单发起支付
 * Class OrderPayServices
 * @package app\services\pay
 */
class OrderPayServices extends BaseServices
{
    /**
     * 支付
     * @var PayServices
     */
    protected $payServices;

    public function __construct(PayServices $services)
    {
        $this->payServices = $services;
    }

    /**
     * 订单发起支付（陪诊）
     * @param array $orderInfo
     * @param string $from
     * @return array|string
     */
    public function orderPay(array $orderInfo, string $from)
    {
        if ($orderInfo['pay_time'] > 0) throw new ValidateException('订单已付款');
        if ($orderInfo['pay_price'] <= 0) {
            $res = ServiceOrder::where('id','=',$orderInfo['id'])->update(['status'=>10,'pay_type'=>'yue','pay_time'=>time()]);
            if(!$res) throw new ValidateException('支付失败');
            return '支付成功';
        }
        $services = app()->make(WechatUserServices::class);
        $openid = $services->uidToOpenid($orderInfo['uid'], $from);
        if (!$openid) throw new ValidateException('无法获取用户openID。无法付款');
        $body = '用户支付';
        $ordersn = $orderInfo['ordersn'].'-'.$orderInfo['ordersn2'];
        $successAction = 'care';
        $wechat_pay = sys_config('pay_weixin_open');
        $allin_pay = sys_config('allinpay_isopen');
        if ($wechat_pay && $allin_pay) {
            $from = 'allinpay';
        } elseif ($allin_pay) {
            $from = 'allinpay';
        } else {
            $from = 'routine';
        }
        $options = [
            'openid'=>$openid
        ];
        return $this->payServices->pay($from, $ordersn,$orderInfo['pay_price'], $successAction, $body, $options);
    }

    /**
     * 订单发起PayPal支付
     * @param array $orderInfo
     * @param string $from
     * @return array|string
     */
    public function orderPayPal(array $orderInfo, string $from)
    {
        if ($orderInfo['paytime'] > 0) {
            throw new ValidateException(lang('The order has been paid'));
        }
        if ($orderInfo['price'] <= 0) {
            throw new ValidateException(lang('The payment need not be made'));
        }
        $openid = '';
        $services = app()->make(WechatUserServices::class);
        $openid = $services->uidToOpenid($orderInfo['uid'], $from);
        if (!$openid) {
            throw new ValidateException(lang('Failed to get user openID. Payment cannot be made'));
        }
        $body = '用户支付运费';
        $ordersn = $orderInfo['ordersn'].'-'.$orderInfo['ordersn2'];
        $successAction = 'jiyun';
        $wechat_pay = sys_config('pay_weixin_open');
        $allin_pay = sys_config('allinpay_isopen');
        if ($wechat_pay && $allin_pay) {
            $from = 'allinpay';
        } elseif ($allin_pay) {
            $from = 'allinpay';
        } else {
            $from = 'routine';
        }
        return $this->payServices->pay($from, $openid, $ordersn, $orderInfo['price'], $successAction, $body);
    }

    /**
     * 订单余额支付（陪诊）
     * @param array $orderInfo
     * @param $uid
     * @return bool[]
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function yueOrderPay(array $orderInfo, $uid)
    {
        if (!$orderInfo) {
            throw new ValidateException(lang('Order does not exist'));
        }
        if ($orderInfo['paytime'] > 0) {
            throw new ValidateException(lang('The order has been paid'));
        }
        $type = 'pay_jiyun';
        /** @var UserServices $services */
        $services = app()->make(UserServices::class);
        $userInfo = $services->getUserInfo($uid);
        if ($userInfo['now_money'] < $orderInfo['price']) {
            throw new ValidateException(lang('Lack of balance'));
        }
        $this->transaction(function () use ($services, $orderInfo, $userInfo, $type) {
            $res = false !== $services->bcDec($userInfo['uid'], 'now_money', $orderInfo['price'], 'uid');
            //写入余额记录
            $now_money = bcsub((string)$userInfo['now_money'], (string)$orderInfo['price'], 2);
            $number = $orderInfo['price'];
            $userMoneyServices = app()->make(UserMoneyServices::class);
            $res = $res && $userMoneyServices->income('pay_jiyun', $userInfo['uid'], $number, $now_money, $orderInfo['id']);
            $res = $res && $this->paySuccess($orderInfo, PayServices::YUE_PAY );//余额支付成功
            if (!$res) {
                throw new ValidateException(lang('Balance payment failure'));
            }
        });
        return ['status' => true];
    }


    /**
     * 支付成功
     * @param array $orderInfo
     * @param string $paytype
     * @param array $other
     * @return bool
     * @throws \Psr\SimpleCache\InvalidArgumentException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function paySuccess(array $orderInfo, $paytype = '', array $other = [])
    {
        $paytime = time();
        $updata = ['paytime' => $paytime, 'paytype' => $paytype, 'status' => 50];
        if ($other && isset($other['trade_no'])) {
            $updata['trade_no'] = $other['trade_no'];
        }
        $res1 = Order::where('id', $orderInfo['id'])->update($updata);
        event('task.send',[$orderInfo['uid'],time(),1,2]);//完成订单支付任务
        /** @var UserServices $services */
        $services = app()->make(UserServices::class);
        $userInfo = $services->getUserInfo($orderInfo['uid']);
        $wx_temp = app()->make(RoutineTemplateListService::class);
        $wechatServices = app()->make(WechatServices::class);
        $openId = $wx_temp->getOpenidByUid($userInfo['uid']);
        if ($openId) {
            $to_message = [
                'order_sn' => $orderInfo['ordersn'],
                'pay_time' => date('Y-m-d H:i:s', $paytime),
                'price' => $orderInfo['price'],
            ];
            $url = '/pages/jiyun/order/detail?order_id='.$orderInfo['id'];
            try {
                $message_type = sys_config('message_type'); // 判断用 订阅消息 还是 公众号模板消息
                if($message_type == 1){  // 1 订阅消息
                    $wx_temp->sendPaySuccess($openId, $to_message, $url);
                }else{  // 2 公众号模板消息
                    //公众号模板消息
                    $wechatServices->sendTemplateUser($orderInfo['uid'], $to_message, 'pay_success_uniform', $url); // 发送给用户
                }
            } catch (\Exception $e) {

            }
        }
        //缓存抽奖次数 除过线下支付
        if (isset($orderInfo['pay_type']) && $orderInfo['pay_type'] != 'offline') {
            /** @var LuckLotteryServices $luckLotteryServices */
            $luckLotteryServices = app()->make(LuckLotteryServices::class);
            $luckLotteryServices->setCacheLotteryNum((int)$orderInfo['uid'], 'order');
        }

        $res = $res1 ;
        return false !== $res;
    }
}
